﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RestSharp;
using Newtonsoft.Json;
using System.Net;

namespace Thanhlichtek.BOS.Ongage
{
    public class OngageService
    {
        private String UserName;
        private String Password;
        private String AccountCode;
        String url = "http://connect.ongage.net";
        private RestClient _restClient;

        private const int RetryNumber = 5;
        private const int RetrySleep = 5000;

        public OngageService(String userName, String password, String accountCode)
        {
            UserName = userName;
            Password = password;
            AccountCode = accountCode;
            _restClient = new RestSharp.RestClient(url);

        }

        public GetListsResult.ListInfo[] GetLists()
        {
            var request = new RestRequest("/api/lists", Method.GET);
            String jsonToSend = "";
            request.AddHeader("X_USERNAME", UserName);
            request.AddHeader("X_PASSWORD", Password);
            request.AddHeader("X_ACCOUNT_CODE", AccountCode);
            request.AddParameter("application/json; charset=utf-8", jsonToSend, ParameterType.RequestBody);
            request.RequestFormat = DataFormat.Json;

            GetListsResult result = null;
            try
            {
                var response = _restClient.Execute(request);
                if (response.StatusCode == HttpStatusCode.Unauthorized)
                {
                    throw new UnauthorizedAccessException("Please check your Ongage user name and password.");
                }
                result = JsonConvert.DeserializeObject<GetListsResult>(response.Content);
            }
            catch (Exception)
            {
                throw;
            }

            return result.payload;
        }

        public Result AddContact(String email, String firstName, String lastName, String listId)
        {
            var request = new RestRequest("/api/contacts", Method.POST);
            Contact contact = new Contact();
            contact.list_id = listId;
            contact.email = email;
            contact.fields.first_name = firstName;
            contact.fields.last_name = lastName;
            contact.fields.email = email;

            string jsonToSend = JsonConvert.SerializeObject(contact);

            request.AddHeader("X_USERNAME", UserName);
            request.AddHeader("X_PASSWORD", Password);
            request.AddHeader("X_ACCOUNT_CODE", AccountCode);
            request.AddParameter("application/json; charset=utf-8", jsonToSend, ParameterType.RequestBody);
            request.RequestFormat = DataFormat.Json;

            Result result = null;
            try
            {
                var response = _restClient.Execute(request);
                result = JsonConvert.DeserializeObject<Result>(response.Content);
            }
            catch (Exception)
            {
                throw;
            }

            return result;

        }

        public Result AddContact(Contact contact)
        {
            for (int i = 0; i <= RetryNumber; i++)
            {
                try
                {
                    var request = new RestRequest("/api/contacts", Method.POST);

                    string jsonToSend = JsonConvert.SerializeObject(contact);

                    request.AddHeader("X_USERNAME", UserName);
                    request.AddHeader("X_PASSWORD", Password);
                    request.AddHeader("X_ACCOUNT_CODE", AccountCode);
                    request.AddParameter("application/json; charset=utf-8", jsonToSend, ParameterType.RequestBody);
                    request.RequestFormat = DataFormat.Json;

                    Result result = null;
                    var response = _restClient.Execute(request);
                    result = JsonConvert.DeserializeObject<Result>(response.Content);

                    if (response.ErrorException != null)
                    {
                        throw response.ErrorException;
                    }

                    return result;
                }
                catch (Exception)
                {
                    if (i == RetryNumber)
                    {
                        return null;
                    }
                    System.Threading.Thread.Sleep(RetrySleep);
                }
            }
            return null;

        }

        public Result UpdateContact(String email, String firstName, String lastName, String listId)
        {
            var request = new RestRequest("/api/contacts", Method.PUT);
            Contact contact = new Contact();
            contact.list_id = listId;
            contact.email = email;
            contact.fields.first_name = firstName;
            contact.fields.last_name = lastName;
            contact.fields.email = email;

            string jsonToSend = JsonConvert.SerializeObject(contact);

            request.AddHeader("X_USERNAME", UserName);
            request.AddHeader("X_PASSWORD", Password);
            request.AddHeader("X_ACCOUNT_CODE", AccountCode);
            request.AddParameter("application/json; charset=utf-8", jsonToSend, ParameterType.RequestBody);
            request.RequestFormat = DataFormat.Json;

            Result result = null;
            try
            {
                var response = _restClient.Execute(request);
                result = JsonConvert.DeserializeObject<Result>(response.Content);
            }
            catch (Exception)
            {
                throw;
            }

            return result;

        }

        public Result UpdateContact(Contact contact)
        {
            for (int i = 0; i <= RetryNumber; i++)
            {
                try
                {
                    var request = new RestRequest("/api/contacts", Method.PUT);

                    string jsonToSend = JsonConvert.SerializeObject(contact);

                    request.AddHeader("X_USERNAME", UserName);
                    request.AddHeader("X_PASSWORD", Password);
                    request.AddHeader("X_ACCOUNT_CODE", AccountCode);
                    request.AddParameter("application/json; charset=utf-8", jsonToSend, ParameterType.RequestBody);
                    request.RequestFormat = DataFormat.Json;

                    Result result = null;
                    var response = _restClient.Execute(request);
                    result = JsonConvert.DeserializeObject<Result>(response.Content);

                    if (response.ErrorException != null)
                    {
                        throw response.ErrorException;
                    }

                    return result;
                }
                catch (Exception)
                {
                    if (i == RetryNumber)
                    {
                        return null;
                    }
                    System.Threading.Thread.Sleep(RetrySleep);
                }
            }

            return null;
        }

        public bool DeleteContact(String contactId)
        {
            for (int i = 0; i <= RetryNumber; i++)
            {
                try
                {
                    var request = new RestRequest("/api/contacts/delete", Method.POST);

                    String jsonToSend = @" { ""contact_id"": """ + contactId + @""" }";


                    request.AddHeader("X_USERNAME", UserName);
                    request.AddHeader("X_PASSWORD", Password);
                    request.AddHeader("X_ACCOUNT_CODE", AccountCode);
                    request.AddParameter("application/json; charset=utf-8", jsonToSend, ParameterType.RequestBody);
                    request.RequestFormat = DataFormat.Json;

                    var response = _restClient.Execute(request);
                    if (response.ErrorException != null)
                    {
                        throw response.ErrorException;
                    }

                    if (response.StatusCode != HttpStatusCode.OK)
                    {
                        if (response.Content.ToUpper().Contains("Contact is already deleted".ToUpper()))
                        {
                            return true;
                        }
                        return false;
                    }
                    return true;

                }
                catch (Exception)
                {
                    if (i == RetryNumber)
                    {
                        return false;
                    }
                    System.Threading.Thread.Sleep(RetrySleep);
                }
            }
            return false;
        }

        public bool SetContactStatus(String email, String listId, ContactStatusAction action)
        {
            for (int i = 0; i <= RetryNumber; i++)
            {
                try
                {
                    var request = new RestRequest("/api/lists/remove", Method.POST);

                    String jsonToSend = @"";
                    jsonToSend += @"{";
                    jsonToSend += @"""list_id"": " + listId+ ",";
                    jsonToSend += @"""emails"":[""" + email + @"""],";
                    jsonToSend += @"""change_to"":""" + Enum.GetName(typeof(ContactStatusAction), action) + @"""";
                    jsonToSend += @"}";


                    request.AddHeader("X_USERNAME", UserName);
                    request.AddHeader("X_PASSWORD", Password);
                    request.AddHeader("X_ACCOUNT_CODE", AccountCode);
                    request.AddParameter("application/json; charset=utf-8", jsonToSend, ParameterType.RequestBody);
                    request.RequestFormat = DataFormat.Json;

                    var response = _restClient.Execute(request);
                    
                    if (response.ErrorException != null)
                    {
                        throw response.ErrorException;
                    }

                    return true;
                }
                catch (Exception)
                {
                    if (i == RetryNumber)
                    {
                        return false;
                    }
                    System.Threading.Thread.Sleep(RetrySleep);
                }
            }
            return false;
        }

        public ContactLookupResult[] GetContactsFromList(String listId)
        {
            var request = new RestRequest("/api/contacts/lookup", Method.POST);

            String jsonToSend = "";
            jsonToSend += @"  {";
            //jsonToSend += @"    ""user_type"": ""active"",";
            jsonToSend += @"    ""offset"": 0,";
            jsonToSend += @"    ""list_id"": " + listId + ",";
            jsonToSend += @"    ""limit"": 99999,";
            jsonToSend += @"    ""criteria"": [{";
            jsonToSend += @"      ""field_name"": ""email"",";
            jsonToSend += @"      ""type"": ""string"",";
            jsonToSend += @"      ""operator"": ""!="",";
            jsonToSend += @"      ""operand"": [ """ + "" + @"""],";
            jsonToSend += @"      ""case_sensitive"": ""0"",";
            jsonToSend += @"      ""condition"": ""and""";
            jsonToSend += @"    }]";
            jsonToSend += @"  }";

            request.AddHeader("X_USERNAME", UserName);
            request.AddHeader("X_PASSWORD", Password);
            request.AddHeader("X_ACCOUNT_CODE", AccountCode);
            request.AddParameter("application/json; charset=utf-8", jsonToSend, ParameterType.RequestBody);
            request.RequestFormat = DataFormat.Json;

            try
            {
                var response = _restClient.Execute(request);
                LookupResult result = JsonConvert.DeserializeObject<LookupResult>(response.Content);
                return result.payload;
            }
            catch (Exception)
            {
                return new ContactLookupResult[]{};
            }

            //return result;
        }

        //public String SearchContactId(String email, String listId)
        //{
        //    var request = new RestRequest("/api/contacts/lookup", Method.POST);

        //    String jsonToSend = "";
        //    jsonToSend += @"  {";
        //    jsonToSend += @"    ""user_type"": ""active"",";
        //    jsonToSend += @"    ""offset"": 0,";
        //    jsonToSend += @"    ""list_id"": " + listId + ",";
        //    jsonToSend += @"    ""limit"": 1,";
        //    jsonToSend += @"    ""criteria"": [{";
        //    jsonToSend += @"      ""field_name"": ""email"",";
        //    jsonToSend += @"      ""type"": ""string"",";
        //    jsonToSend += @"      ""operator"": ""="",";
        //    jsonToSend += @"      ""operand"": [ """ + email + @"""],";
        //    jsonToSend += @"      ""case_sensitive"": ""0"",";
        //    jsonToSend += @"      ""condition"": ""and""";
        //    jsonToSend += @"    }]";
        //    jsonToSend += @"  }";

        //    request.AddHeader("X_USERNAME", UserName);
        //    request.AddHeader("X_PASSWORD", Password);
        //    request.AddHeader("X_ACCOUNT_CODE", AccountCode);
        //    request.AddParameter("application/json; charset=utf-8", jsonToSend, ParameterType.RequestBody);
        //    request.RequestFormat = DataFormat.Json;

        //    String result = "";
        //    try
        //    {
        //        var response = _restClient.Execute(request);
        //        return GetJsonValue(response.Content, "id");
        //    }
        //    catch (Exception)
        //    {
        //        throw;
        //    }

        //    return result;
        //}

        //private String GetJsonValue(String jsonString, String key)
        //{
        //    string[] splitted = jsonString.Split(new char[] { ':' });
        //    for (int i = 0; i < splitted.Length; i++)
        //    {
        //        string item = splitted[i];
        //        if (item.Contains(@"""" + key + @"""") && i < splitted.Length - 1)
        //        {
        //            return splitted[i + 1].Split(new char[]{'"'})[1];
        //        }
        //    }
        //    return "";
        //}
    }

}
